package com.zhu.rtda;

/**
 * Java虚拟机栈
 * 使用链表实现，每个节点是一个栈帧（Frame）
 */
public class Stack {

    // 栈的最大容量（最多可容纳的帧数）
    private int maxSize;

    // 当前栈中帧的数量
    private int size;

    // 栈顶指针，指向当前栈顶帧
    private Frame top;

    /**
     * 构造一个指定最大容量的虚拟机栈
     * @param maxSize 栈的最大帧数
     */
    public Stack(int maxSize) {
        this.maxSize = maxSize;
        this.size = 0;
        this.top = null;
    }

    /**
     * 将一个栈帧推入栈顶
     * @param frame 要推入的帧
     * @throws StackOverflowError 如果栈已满
     */
    public void push(Frame frame) {
        if (size >= maxSize) {
            throw new StackOverflowError();
        }
        // 如果栈非空，新帧的lower指向当前栈顶帧（形成链表）
        if (top != null) {
            frame.setLower(top);
        }
        // 更新栈顶为新帧
        top = frame;
        size++;
    }

    /**
     * 弹出栈顶帧
     * @return 被弹出的栈帧
     * @throws RuntimeException 如果栈为空（程序错误）
     */
    public Frame pop() {
        if (top == null) {
            throw new RuntimeException("jvm stack is empty!");
        }
        Frame topFrame = top;
        // 栈顶指向下一层帧
        top = top.getLower();
        // 清除被弹出帧的lower引用，帮助GC回收
        topFrame.setLower(null);
        size--;
        return topFrame;
    }

    /**
     * 获取栈顶帧，但不弹出
     * @return 栈顶帧
     * @throws RuntimeException 如果栈为空（程序错误）
     */
    public Frame top() {
        if (top == null) {
            throw new RuntimeException("jvm stack is empty!");
        }
        return top;
    }

    /**
     * 获取栈的当前大小（帧的数量）
     * @return 当前帧数
     */
    public int size() {
        return size;
    }

    /**
     * 栈是否为空
     * @return true if empty
     */
    public boolean isEmpty() {
        return top == null;
    }

    /**
     * 获取栈的最大容量
     * @return 最大帧数
     */
    public int getMaxSize() {
        return maxSize;
    }
}
